package com.yhx.security.gfoBank.api.com.test;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Base64;

import com.yhx.security.gfoBank.api.com.gmcrypto.mf.gm.SM2Util;
import com.yhx.security.gfoBank.api.com.gmcrypto.mf.gm.SM4Util;
import com.yhx.security.gfoBank.api.com.key.FileHelper;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.lang.RandomStringUtils;



public class SM2RequestTestXML {

	public static void main(String[] args) {
		try{
			String merchantPriKey="test001.pvk";
			String merchantPubKey="test001.puk";
			
			String guangfaPubKey="guangfa.puk";
			String encoding="GBK";
			
			String path=SM2RequestTestXML.class.getClassLoader().getResource("").getPath();
			File file=new File(path+"/xml/sendMsgCode.xml");
			FileInputStream fi=new FileInputStream(file);
			BufferedReader bf=new BufferedReader(new InputStreamReader(fi));
			StringBuffer strBuffer=new StringBuffer();
			String line=null;
			while( (line=bf.readLine())!=null){
				strBuffer.append("\n").append(line);
			}
			String reqStr=strBuffer.substring(1);
			System.out.println("������ԭ�ģ�\n"+reqStr);
			
			
			String contentType="application/xml";
			
			//1��ǩ��
			
			String signature=SM2RequestTestXML.sign(reqStr,merchantPriKey,encoding);
			System.out.println("������ǩ�������\n"+signature);
			String certId= MD5.getMD5(merchantPubKey);
			
			//2������
			RandomStringUtils rs = new RandomStringUtils();
			String verifyChars = "123457890abcdefghijklmnopqrstuvwxyz"; 
			String encryptKey = rs.random(16, verifyChars).toUpperCase();
			
			byte[] encryptBytes= SM4Util.encryptCBC(reqStr.getBytes(encoding), encryptKey.getBytes(), encryptKey.getBytes());
			reqStr=Base64.getEncoder().encodeToString(encryptBytes);
			
			System.out.println("�����ļ��ܽ����\n"+reqStr);
			
			//3��ʹ�ù㷢��Կ��������м���
			String encryptKey1=SM2RequestTestXML.sm2EncryptString(encryptKey, guangfaPubKey, encoding);
			
			//4������post����
			String requestUrl="http://218.13.4.194:30041/cop-gateway-app/API/accountService/sendMsgCode/1.0.0";
			PostMethod postMethod = new PostMethod(requestUrl);
			
			HttpClient httpClient = new HttpClient();
		    httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(5000);
		    httpClient.getHttpConnectionManager().getParams().setSoTimeout(30000);
		    
		    postMethod.setRequestHeader("signature",signature);
		    postMethod.setRequestHeader("signType","SM2");
		    postMethod.setRequestHeader("encryptType","SM4");
		    postMethod.setRequestHeader("encryptKey",encryptKey1);
		    postMethod.setRequestHeader("certId",certId);
		    
		    StringRequestEntity sre = new StringRequestEntity(reqStr, contentType,encoding);
		    postMethod.setRequestEntity(sre);
		    String result=null;
		    String respSignature=null;
		    try{
		    	int status=httpClient.executeMethod(postMethod);
		    	if (status == HttpStatus.SC_OK) {
		    		result=postMethod.getResponseBodyAsString();
		    		respSignature=postMethod.getResponseHeader("signature").getValue();
		    	}else{
		    		System.out.println("HTTPException HttpStatus:"+status);
		    	}
		    }catch (IOException e) {
		    	e.printStackTrace();
		    }
		    
		    System.out.println("���ر��ģ�\n"+result);
		    
		    //5������
		     byte[] decryptBytes=SM4Util.decryptCBC(Base64.getDecoder().decode(result), encryptKey.getBytes(), encryptKey.getBytes());
		     String respStr=new String(decryptBytes,encoding);
		     System.out.println("���ر��Ľ��ܽ����\n"+respStr);
		    
		    //6����ǩ
		    boolean veryfyResult=SM2RequestTestXML.veryfySign(respStr, respSignature, guangfaPubKey, encoding);
		    System.out.println("���ر�����ǩ�����\n"+veryfyResult);
		    
		    
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
	public static String sign(String srcString,String pvkName,String encoding) throws Exception{
		String path=SM2RequestTestXML.class.getClassLoader().getResource("").getPath();
		//byte[] pvkBytes= FileHelper.read(path+"/"+pvkName);
		byte[] pvkBytes= FileHelper.read("D:\\Coding\\threadStudy\\src\\main\\webapp\\eleme001.pvk");
		if(pvkBytes.length>32) {
			pvkBytes= SM2Util.getPrivateKey(pvkBytes);
		}
		byte[] signedBytes=SM2Util.sign(pvkBytes, srcString.getBytes(encoding));
		return Base64.getEncoder().encodeToString(signedBytes);
	}
	
	public static boolean veryfySign(String srcString,String respSignature,String pukName,String encoding) throws Exception{
		String path=SM2RequestTestXML.class.getClassLoader().getResource("").getPath();
		//byte[] pukBytes=FileHelper.read(path+"/"+pukName);
		byte[] pukBytes= FileHelper.read("D:\\Coding\\threadStudy\\src\\main\\webapp\\eleme001.puk");
		if(pukBytes.length>64) {
			pukBytes=SM2Util.getPublicKey(pukBytes);
		}
		return SM2Util.verifySign(pukBytes, srcString.getBytes(encoding), Base64.getDecoder().decode(respSignature));
	}
	
	public static String sm2EncryptString(String srcString,String pukName,String encoding) throws Exception{
		String path=SM2RequestTestXML.class.getClassLoader().getResource("").getPath();
		//byte[] pukBytes=FileHelper.read(path+"/"+pukName);
		byte[] pukBytes=FileHelper.read("D:\\Coding\\threadStudy\\src\\main\\webapp\\eleme001.puk");
		if(pukBytes.length>64) {
			pukBytes=SM2Util.getPublicKey(pukBytes);
		}
		byte[] encryptBytes=SM2Util.encrypt(pukBytes, srcString.getBytes(encoding));
		return Base64.getEncoder().encodeToString(encryptBytes);
	}
}
